package crmdna.api.endpoint;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;
import javax.inject.Named;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.google.appengine.api.users.User;

import crmdna.client.Client;
import crmdna.common.APIResponse;
import crmdna.common.APIResponse.Status;
import crmdna.common.Constants;
import crmdna.common.Utils;
import crmdna.common.Utils.Currency;
import crmdna.practice.Practice;
import crmdna.practice.Practice.PracticeProp;
import crmdna.program.Program;
import crmdna.program.ProgramProp;
import crmdna.program.SessionProp;

@Api(name = "program", clientIds = { "220866004543.apps.googleusercontent.com",
		com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID })
public class ProgrameApi {
	@ApiMethod(path = "create", httpMethod = HttpMethod.POST)
	public APIResponse create(
			@Named("client") String client,
			@Named("groupId") long groupId,
			@Named("programTypeId") long programTypeId,
			@Named("venueId") long venueId,
			@Named("teacherId") long teacherId,
			@Named("startYYYYMMDD") int startYYYYMMDD,
			@Named("endYYYYMMDD") int endYYYYMMDD,
			@Named("numBatches") int numBatches,
			@Nullable @Named("description") String description,
			@Nullable @Named("fees") Double fees,
			@Nullable @Named("feeCurrency") Currency ccy,
			@Nullable @Named("specialInstructionsFreeText") String specialInstruction,
			@Nullable @Named("batch1SessionTimingsFreeText") List<String> batch1SessionTimings,
			@Nullable @Named("batch2SessionTimingsFreeText") List<String> batch2SessionTimings,
			@Nullable @Named("batch3SessionTimingsFreeText") List<String> batch3SessionTimings,
			@Nullable @Named("batch4SessionTimingsFreeText") List<String> batch4SessionTimings,
			@Nullable @Named("batch5SessionTimingsFreeText") List<String> batch5SessionTimings,
			User user) {

		try {
			if (fees == null)
				fees = 0.0;

			ProgramProp programProp = Program.create(client, groupId,
					programTypeId, venueId, teacherId, startYYYYMMDD,
					endYYYYMMDD, numBatches, description, fees, ccy,
					Utils.getLoginEmail(user));

			programProp = Program.setSpecialInstruction(client,
					programProp.programId, specialInstruction);

			programProp = Program.setSessionTimings(client,
					programProp.programId, batch1SessionTimings,
					batch2SessionTimings, batch3SessionTimings,
					batch4SessionTimings, batch5SessionTimings);

			return new APIResponse(Status.SUCCESS, programProp);

		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}

	@ApiMethod(path = "query", httpMethod = HttpMethod.GET)
	public APIResponse query(@Named("client") String client,
			@Nullable @Named("startYYYYMMDD") Integer startYYYYMMDD,
			@Nullable @Named("endYYYYMMDD") Integer endYYYYMMDD,
			@Nullable @Named("programTypeId") Long programTypeId,
			@Nullable @Named("groupIds") Set<Long> groupIds,
			@Nullable @Named("venueId") Long venueId,
			@Nullable @Named("limit") Integer limit) {

		try {
			List<ProgramProp> programProps = Program.query(client,
					startYYYYMMDD, endYYYYMMDD, programTypeId, groupIds,
					venueId, limit);

			return new APIResponse(Status.SUCCESS, programProps);

		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}

	@ApiMethod(path = "update", httpMethod = HttpMethod.POST)
	public APIResponse update(
			@Named("client") String client,
			@Named("programId") long programId,
			@Nullable @Named("newVenueId") Long newVenueId,
			@Nullable @Named("newTeacherId") Long newTeacherId,
			@Nullable @Named("newStartYYYYMMDD") Integer newStartYYYYMMDD,
			@Nullable @Named("newEndYYYYMMDD") Integer newEndYYYYMMDD,
			@Nullable @Named("newNumBatches") Integer newNumBatches,
			@Nullable @Named("newDescription") String newDescription,
			@Nullable @Named("fees") Double fees,
			@Nullable @Named("feeCurrency") Currency ccy,
			@Nullable @Named("specialInstructionsFreeText") String specialInstruction,
			@Nullable @Named("batch1SessionTimingsFreeText") List<String> batch1SessionTimings,
			@Nullable @Named("batch2SessionTimingsFreeText") List<String> batch2SessionTimings,
			@Nullable @Named("batch3SessionTimingsFreeText") List<String> batch3SessionTimings,
			@Nullable @Named("batch4SessionTimingsFreeText") List<String> batch4SessionTimings,
			@Nullable @Named("batch5SessionTimingsFreeText") List<String> batch5SessionTimings,
			User user) {

		try {
			ProgramProp programProp = Program.update(client, programId,
					newVenueId, newTeacherId, newStartYYYYMMDD, newEndYYYYMMDD,
					newNumBatches, newDescription, fees, ccy,
					Utils.getLoginEmail(user));

			programProp = Program.setSpecialInstruction(client,
					programProp.programId, specialInstruction);

			programProp = Program.setSessionTimings(client,
					programProp.programId, batch1SessionTimings,
					batch2SessionTimings, batch3SessionTimings,
					batch4SessionTimings, batch5SessionTimings);

			return new APIResponse(Status.SUCCESS, programProp);

		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}

	@ApiMethod(path = "rename", httpMethod = HttpMethod.GET)
	public APIResponse rename(@Named("client") String client,
			@Named("practiceId") long practiceId,
			@Named("newDisplayName") String newDisplayName, User user) {

		try {
			Client.ensureValid(client);
			PracticeProp prop = Practice.rename(client, practiceId,
					newDisplayName, Utils.getLoginEmail(user));

			return new APIResponse(Status.SUCCESS, prop);
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}

	@ApiMethod(path = "delete", httpMethod = HttpMethod.GET)
	public APIResponse delete(@Named("client") String client,
			@Named("practiceId") long practiceId, User user) {

		try {
			Client.ensureValid(client);
			Practice.delete(client, practiceId, Utils.getLoginEmail(user));

			return new APIResponse(Status.SUCCESS, "Center [" + practiceId
					+ "] deleted");
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}

	@ApiMethod(path = "getOngoingSessions", httpMethod = HttpMethod.GET)
	public APIResponse getOngoingSessions(
			@Nullable @Named("client") String client,
			@Named("dateYYYYMMDD") int dateYYYYMMDD, User user) {
		try {

			if (null == client)
				client = Constants.CLIENT_ISHA;

			List<SessionProp> sessionProps = Program.getOngoingSessions(client,
					dateYYYYMMDD, Utils.getLoginEmail(user));
			new ArrayList<>();

			return new APIResponse(Status.SUCCESS, sessionProps);

		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
}
